﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using System.Xml;
using System.Xml.XPath;

/// <summary>
/// Summary description for Assessment
/// </summary>
/// 

public class Assessment
{
    public Assessment(string FileName, string URL)
    {
        string xmlText = "";
        string[] buffer;
        System.IO.StreamReader sr = new System.IO.StreamReader(FileName);
        //while (!sr.EndOfStream)
        //{
        //    buffer = sr.ReadLine();
        //    if (buffer.Contains("xmlns"))
        //        xmlText += "\n" + "<questestinterop>";
        //    else if (buffer.Contains("!DOCTYPE"))
        //        xmlText += "";
        //    else
        //        xmlText += buffer;
        //}
        buffer = sr.ReadToEnd().Split(new char[] {'>'});
        foreach (string bline in buffer)
        {
            if (bline.Contains("xmlns"))
                xmlText += "\n" + "<questestinterop>";
            else if (bline.Contains("!DOCTYPE"))
                xmlText += "";
            else
                xmlText += bline + ">";
        }
        sr.Close();
        xmlText = xmlText.Replace("'", "`");
        xmlText = xmlText.Remove(xmlText.Length - 1);
		
        XmlReader xr = XmlReader.Create(new System.IO.StringReader(xmlText));
        XPathDocument xd = new XPathDocument(xr);
        XPathNavigator xn = xd.CreateNavigator();

        AssessmentItems = new List<AssessmentItem>();

        foreach (XPathNavigator node in xn.Select("//item"))
        {
            AssessmentItem ai = new AssessmentItem();

            ai.ItemTitle = node.GetAttribute("title", "");
            if (ai.ItemTitle == "")
                ai.ItemTitle = "Item: " + Convert.ToString(AssessmentItems.Count + 1);

            foreach (XPathNavigator snode1 in node.Select("./itemmetadata/qtimetadata/qtimetadatafield/fieldlabel[. = 'cc_profile']/parent::node()/fieldentry"))
            {
                if (snode1.Value == "cc.multiple_choice.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.MultipleChoiceSingleAnswer;
                if (snode1.Value == "cc.true_false.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.MultipleChoiceSingleAnswer;
                if (snode1.Value == "cc.fib.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.Text;
                if (snode1.Value == "cc.multiple_response.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.MultipleChiceMultipleAnswer;
                if (snode1.Value == "cc.pattern_match.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.PatternMatch;
                if (snode1.Value == "cc.essay.v0p1")
                    ai.ItemType = AssessmentItem.ItemTypes.Essay;
            }

            foreach (XPathNavigator picNode in node.Select("./presentation/material/matimage"))
                ai.ImageURL = URL +  picNode.GetAttribute("uri", "");
            foreach (XPathNavigator picNode in node.Select("./presentation/flow/response_lid/render_hotspot/material/matimage"))
                ai.ImageURL = URL + picNode.GetAttribute("uri", "");

            foreach (XPathNavigator snode2 in node.Select("./presentation/flow/material/mattext"))
                ai.ItemText = snode2.Value;
            foreach (XPathNavigator snode2 in node.Select("./presentation/material/mattext"))
                ai.ItemText = snode2.Value;
            foreach (XPathNavigator snode2 in node.Select("./presentation/flow/response_lid/material/mattext"))
                ai.ItemText = snode2.Value;

            foreach (XPathNavigator snode3 in node.Select("./presentation/response_lid/render_choice/response_label"))
            {
                AssessmentAnswer aa = new AssessmentAnswer();
                aa.Identifier = snode3.GetAttribute("ident", "");

                foreach (XPathNavigator snode4 in snode3.Select("./material/mattext"))
                    aa.AnswerText = snode4.Value;
                foreach (XPathNavigator snode4 in snode3.Select("./flow_mat/material/mattext"))
                    aa.AnswerText = snode4.Value;
                ai.Answers.Add(aa);
            }

            foreach (XPathNavigator snode3 in node.Select("./presentation/flow/response_lid/render_choice/response_label"))
            {
                AssessmentAnswer aa = new AssessmentAnswer();
                aa.Identifier = snode3.GetAttribute("ident", "");

                foreach (XPathNavigator snode4 in snode3.Select("./material/mattext"))
                    aa.AnswerText = snode4.Value;
                foreach (XPathNavigator snode4 in snode3.Select("./flow_mat/material/mattext"))
                    aa.AnswerText = snode4.Value;
                ai.Answers.Add(aa);
            }

            foreach (XPathNavigator snode3 in node.Select("./presentation/flow/response_lid/render_choice/flow_label/response_label"))
            {
                AssessmentAnswer aa = new AssessmentAnswer();
                aa.Identifier = snode3.GetAttribute("ident", "");

                foreach (XPathNavigator snode4 in snode3.Select("./material/mattext"))
                    aa.AnswerText = snode4.Value;
                foreach (XPathNavigator snode4 in snode3.Select("./flow_mat/material/mattext"))
                    aa.AnswerText = snode4.Value;
                ai.Answers.Add(aa);
            }

            foreach (XPathNavigator snode3 in node.Select("./presentation/response_str"))
            {
                AssessmentAnswer aa = new AssessmentAnswer();
                aa.Identifier = snode3.GetAttribute("ident", "");
                ai.Answers.Add(aa);
            }

            foreach (XPathNavigator snode5 in node.Select("./resprocessing/outcomes"))
            {
                if (snode5.GetAttribute("varname", "") == "SCORE")
                {
                    Int32.TryParse(snode5.GetAttribute("maxscore", ""), out ai.MaxScore);
                    Int32.TryParse(snode5.GetAttribute("minscore", ""), out ai.MinScore);
                }
            }

            foreach (XPathNavigator snode6 in node.Select("./resprocessing/respcondition"))
            {
                foreach (AssessmentAnswer aa in ai.Answers)
                {
                    foreach (XPathNavigator snode7 in snode6.Select("./conditionvar/varequal[. = '" + aa.Identifier + "']/parent::node()/parent::node()"))
                    {
                        AssessmentResponse rsp = new AssessmentResponse();
                        rsp.RefId = aa.Identifier;

                        foreach (XPathNavigator snode8 in snode7.Select("./displayfeedback"))
                        {
                            FeedBack fb = new FeedBack();
                            fb.RefId = snode8.GetAttribute("linkrefid", "");
                            rsp.FeedBacks.Add(fb);
                        }

                        foreach (XPathNavigator snode9 in snode7.Select("./setvar"))
                        {
                            if (snode9.GetAttribute("varname", "") == "SCORE")
                                Int32.TryParse(snode9.Value, out rsp.Score);
                        }

                        aa.Responses.Add(rsp);
                    }

                    foreach (XPathNavigator snode7 in snode6.Select("./conditionvar/varsubstring[. = '" + aa.Identifier + "']/parent::node()/parent::node()"))
                    {
                        AssessmentResponse rsp = new AssessmentResponse();
                        rsp.RefId = aa.Identifier;

                        foreach (XPathNavigator snode8 in snode7.Select("./displayfeedback"))
                        {
                            FeedBack fb = new FeedBack();
                            fb.RefId = snode8.GetAttribute("linkrefid", "");
                            rsp.FeedBacks.Add(fb);
                        }

                        foreach (XPathNavigator snode9 in snode7.Select("./setvar"))
                        {
                            if (snode9.GetAttribute("varname", "") == "SCORE")
                                Int32.TryParse(snode9.Value, out rsp.Score);
                        }

                        aa.Responses.Add(rsp);
                    }

                    foreach (XPathNavigator snode7 in snode6.Select("./conditionvar/varequal[@respident = '" + aa.Identifier + "']/parent::node()/parent::node()"))
                    {
                        AssessmentResponse rsp = new AssessmentResponse();
                        rsp.RefId = aa.Identifier;

                        foreach (XPathNavigator snode8 in snode7.Select("./displayfeedback"))
                        {
                            FeedBack fb = new FeedBack();
                            fb.RefId = snode8.GetAttribute("linkrefid", "");
                            rsp.FeedBacks.Add(fb);
                        }

                        foreach (XPathNavigator snode9 in snode7.Select("./setvar"))
                        {
                            if (snode9.GetAttribute("varname", "") == "SCORE")
                                Int32.TryParse(snode9.Value, out rsp.Score);
                        }

                        foreach (XPathNavigator patAnswer in snode7.Select("./conditionvar/varequal"))
                            rsp.Pattern = patAnswer.Value;

                        aa.Responses.Add(rsp);
                    }

                    foreach (XPathNavigator snode7 in snode6.Select("./conditionvar/varsubstring[@respident = '" + aa.Identifier + "']/parent::node()/parent::node()"))
                    {
                        AssessmentResponse rsp = new AssessmentResponse();
                        rsp.RefId = aa.Identifier;

                        foreach (XPathNavigator snode8 in snode7.Select("./displayfeedback"))
                        {
                            FeedBack fb = new FeedBack();
                            fb.RefId = snode8.GetAttribute("linkrefid", "");
                            rsp.FeedBacks.Add(fb);
                        }

                        foreach (XPathNavigator snode9 in snode7.Select("./setvar"))
                        {
                            if (snode9.GetAttribute("varname", "") == "SCORE")
                                Int32.TryParse(snode9.Value, out rsp.Score);
                        }

                        foreach (XPathNavigator patAnswer in snode7.Select("./conditionvar/varsubstring"))
                            rsp.Pattern = patAnswer.Value;

                        aa.Responses.Add(rsp);
                    }

                    foreach (XPathNavigator snode7 in snode6.Select("./conditionvar/varequal[. = '" + aa.AnswerText.ToLower() + "']/parent::node()/parent::node()"))
                    {
                        AssessmentResponse rsp = new AssessmentResponse();
                        rsp.RefId = aa.Identifier;

                        foreach (XPathNavigator snode8 in snode7.Select("./displayfeedback"))
                        {
                            FeedBack fb = new FeedBack();
                            fb.RefId = snode8.GetAttribute("linkrefid", "");
                            rsp.FeedBacks.Add(fb);
                        }

                        foreach (XPathNavigator snode9 in snode7.Select("./setvar"))
                        {
                            if (snode9.GetAttribute("varname", "") == "SCORE")
                                Int32.TryParse(snode9.Value, out rsp.Score);
                        }

                        aa.Responses.Add(rsp);
                    }
                }
            }

            foreach (AssessmentAnswer aa in ai.Answers)
            {
                foreach (AssessmentResponse rsp in aa.Responses)
                {
                    foreach (FeedBack fb in rsp.FeedBacks)
                    {
                        foreach (XPathNavigator snode10 in node.Select("./itemfeedback[@ident = '" + fb.RefId + "']/flow_mat/material/mattext"))
                            fb.FeedBackText = snode10.Value;
                        foreach (XPathNavigator snode10 in node.Select("./itemfeedback[@ident = '" + fb.RefId + "']/material/mattext"))
                            fb.FeedBackText = snode10.Value;
                    }
                }
            }

            AssessmentItems.Add(ai);
        }
    }
    public string xmlName;
    public string Title;
    public List<AssessmentItem> AssessmentItems;
}

public class AssessmentItem
{
    public AssessmentItem()
    {
        AssessmentItemID = -1;
        ItemTitle = "";
        ItemText = "";
        ItemType = ItemTypes.MultipleChoiceSingleAnswer;
        Answers = new List<AssessmentAnswer>();
        AnswerGiven = "";
    }

    public int AssessmentItemID;
    public string ItemTitle;
    public string ItemText;
    public string ImageURL;
    public enum ItemTypes { MultipleChoiceSingleAnswer, MultipleChiceMultipleAnswer, Text, PatternMatch, Essay }
    public ItemTypes ItemType;
    public List<AssessmentAnswer> Answers;
    public int MaxScore;
    public int MinScore;
    public string AnswerGiven;
}

public class AssessmentAnswer
{
    public AssessmentAnswer()
    {
        AnswerText = "";
        Identifier = "";
        Correct = false;
        Responses = new List<AssessmentResponse>();
    }

    public AssessmentAnswer(string Answer, string Ident)
    {
        AnswerText = Answer;
        Identifier = Ident;
        Correct = false;
        Responses = new List<AssessmentResponse>();
    }

    public string AnswerText { get; set; }
    public string Identifier { get; set; }
    public bool Correct;
    public List<AssessmentResponse> Responses;
}

public class AssessmentResponse
{
    public AssessmentResponse()
    {
        RefId = "";
        FeedBacks = new List<FeedBack>();
        Score = -1;
    }
    public AssessmentResponse(string rid)
    {
        RefId = rid;
        FeedBacks = new List<FeedBack>();
        Score = -1;
    }
    public string RefId;
    public int Score;
    public string Pattern;
    public List<FeedBack> FeedBacks;
}

public class FeedBack
{
    public FeedBack()
    {
        RefId = "";
        FeedBackText = "";
    }
    public FeedBack(string rid)
    {
        RefId = rid;
        FeedBackText = "";
    }
    public string RefId;
    public string FeedBackText;
}